﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using Interfaces;

namespace Pozr
{
    /// <summary>
    /// The class describes an event
    /// </summary>
    public class EventDescription
    {
        public static int id_counter = 1;

        public int Id { get; private set; }
        private string[] eventMembers;
        private string description;
        private short minRelevance;
        private ContextMatchesHandler eventHandler;

        public EventDescription(string[] _eventMembers, string _description, short _minRelevance, ContextMatchesHandler _eventHandler)
        {
            Id = id_counter++;
            eventMembers = _eventMembers;
            description = _description;
            minRelevance = _minRelevance;
            eventHandler = _eventHandler;
        }

        public void Add(string[] _eventMembers)
        {
            eventMembers = eventMembers.Intersect(_eventMembers).ToArray();
        }

        public int CheckRelevance(string[] _currentContext)
        {
            short relevance = 0;
            foreach (string s in _currentContext)
            {
                foreach (string r in eventMembers)
                {
                    if (String.Compare(s, r) == 0)
                        relevance++;
                }
            }

            if (relevance >= minRelevance)
            {
                this.eventHandler(this, this.Id, relevance);
            }
            return relevance;
        }
    }

    /// <summary>
    /// Stores and manages event descriptors
    /// </summary>
    public class EventEngine
    {
        private List<EventDescription> events = new List<EventDescription>();

        public EventEngine()
        {
            Middleware.PluginServices.ContextChanged += new ContextChangedHandler(Plugins_ContextChanged);
            Console.WriteLine("EventEngine started.");
        }

        void Plugins_ContextChanged(object sender)
        {
            Interfaces.PositionOriginator[] originators = { Interfaces.PositionOriginator.Cell, Interfaces.PositionOriginator.Wifi };
            string[] context = Middleware.PositionHandler.GetCurrentContextHashes(originators);

            foreach (EventDescription ed in events)
            {
                ed.CheckRelevance(context);
            }
        }

        public bool AddEvent(EventDescription _event)
        {
            try
            {
                events.Add(_event);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                return false;
            }
            return true;
        }

        public int AddEvent(string description, short minRelevance, ContextMatchesHandler handler, PositionOriginator[] originators)
        {
            events.Add(new EventDescription(Middleware.PositionHandler.GetCurrentContextHashes(originators), description, minRelevance, handler));
            return EventDescription.id_counter;
        }

        public int AddEvent(string description, short minRelevance, ContextMatchesHandler handler, string[] members)
        {
            events.Add(new EventDescription(members, description, minRelevance, handler));
            return EventDescription.id_counter;
        }

        public bool MergeEvent(int id, string[] members)
        {
            foreach (EventDescription ed in events)
            {
                if (ed.Id == id)
                {
                    ed.Add(members);
                    return true;
                }
            }
            return false;
        }

        public bool RemoveEvent(int _id)
        {
            foreach (EventDescription ed in events)
            {
                if (ed.Id == _id)
                {
                    events.Remove(ed);
                    return true;
                }
            }
            return false;
        }
    }
}
